# -*- coding: utf-8 -*-
import atexit
import sys
import ssl
from pyVim.connect import Disconnect, SmartConnect
from pyVmomi import vim
from pyVim.task import WaitForTask


class vCenterManager():
    def __init__(self, vcenter_ip, vcenter_port, vcenter_user, vcenter_pwd):
        self.vcenter_ip = vcenter_ip
        self.vcenter_port = vcenter_port
        self.vcenter_user = vcenter_user
        self.vcenter_pwd = vcenter_pwd
        self.context = None
        self.si = None
        self.content = None

        # 建立与vSphere的连接
        if hasattr(ssl, '_create_unverified_context'):
            self.context = ssl._create_unverified_context()
        self.si = SmartConnect(host=self.vcenter_ip, port=self.vcenter_port,
                               user=self.vcenter_user, pwd=self.vcenter_pwd,
                               sslContext=self.context)
        if not self.si:
            print("请检查vc账号密码")
            sys.exit(1)

        self.content = self.si.RetrieveContent()
        atexit.register(Disconnect, self.si)


    def vm_clone(self, src_vmname, dest_vmname, cluster_name, datastore_name, newCPU, newMemMB, newIP, newSubMask,
                 newGateWay, newDNS):
        if not src_vmname or not dest_vmname:
            print("源或目标虚拟机设置错误")
            sys.exit(1)

        # 查找源虚拟机对象
        src_vm = self.get_obj(self.content, [vim.VirtualMachine], src_vmname)
        if not src_vm:
            raise SystemExit("源虚拟机未找到")

        # 配置目标存储位置
        datastore = self.get_obj(self.content, [vim.Datastore], datastore_name)
        if not datastore:
            raise SystemExit("存储地址未找到")

        # 查找目标资源池（使用集群的默认资源池）
        cluster = self.get_obj(self.content, [vim.ClusterComputeResource], cluster_name)
        if not cluster:
            raise SystemExit("目标集群未找到")

        resource_pool = cluster.resourcePool
        if not resource_pool:
            raise SystemExit("目标资源池未找到")

        # 配置目标虚拟机的存储和资源池
        relocate_spec = vim.vm.RelocateSpec()
        relocate_spec.datastore = datastore
        relocate_spec.pool = resource_pool

        # 硬件配置
        config_spec = vim.vm.ConfigSpec(
            name=dest_vmname,
            numCPUs=int(newCPU),
            memoryMB=int(newMemMB),
            deviceChange=[]  # 添加或修改设备
        )

        # 自定义网络设置
        customization_spec = self.create_customization_spec(
            dest_vmname,
            ip_address=newIP,
            subnet_mask=newSubMask,
            gateway=newGateWay,
            dns=newDNS
        )

        # 克隆配置
        clone_spec = vim.vm.CloneSpec(
            powerOn=False,  # 克隆后不启动
            template=False,  # 克隆后不是模板
            location=relocate_spec,
            config=config_spec,  # 应用CPU内存设置
            customization=customization_spec  # 应用网络设置
        )

        # 执行克隆任务
        print("开始克隆虚拟机...")
        task = src_vm.CloneVM_Task(folder=src_vm.parent, name=dest_vmname, spec=clone_spec)
        WaitForTask(task)
        print("虚拟机克隆完成")
        msg="请手动替换网络适配器，检查网络配置"
        return msg

    @staticmethod
    def get_obj(content, vimtype, name):
        """获取vSphere对象"""
        obj = None
        container = content.viewManager.CreateContainerView(content.rootFolder, vimtype, True)
        for c in container.view:
            if c.name == name:
                obj = c
                break
        container.Destroy()
        return obj

    @staticmethod
    def create_customization_spec(hostname, ip_address, gateway, dns, subnet_mask):
        """创建自定义规格"""
        # 网络适配器设置
        adapter_map = vim.vm.customization.AdapterMapping()
        adapter_map.adapter = vim.vm.customization.IPSettings(
            ip=vim.vm.customization.FixedIp(ipAddress=ip_address),
            subnetMask=subnet_mask,
            gateway=[gateway],
            dnsServerList=[dns]
        )
        # 全局IP设置
        global_ip = vim.vm.customization.GlobalIPSettings(dnsServerList=dns)
        # Linux系统标识
        identity = vim.vm.customization.LinuxPrep(
            domain="local",
            hostName=vim.vm.customization.FixedName(name=hostname)
        )
        # 自定义规格
        customization_spec = vim.vm.customization.Specification()
        customization_spec.nicSettingMap = [adapter_map]
        customization_spec.globalIPSettings = global_ip
        customization_spec.identity = identity
        return customization_spec


if __name__ == '__main__':

    vc = vCenterManager(vcenter_ip, vcenter_port, vcenter_user, vcenter_pwd)
    msg=vc.vm_clone(src_vm_name, dest_vm_name, cluster_name, datastore_name, newCPU, newMemMB, newIP, newSubMask,
                newGateWay, newDNS)
    print(msg)
sys.exit(0)
